﻿
#include "zyLayoutFlexGrid.h"

DarkMoonUI::zyLayoutFlexGrid::zyLayoutFlexGrid()
{
	SetMember(L"this", (LONG_PTR)this);
	m_obj->setWndProc(zyLayoutFlexGrid_WndProc);
	m_obj->setDestroy(zyLayoutFlexGrid_Destroy);
	SetMember(L"ColCount", 2);
}
DarkMoonUI::zyLayoutFlexGrid::~zyLayoutFlexGrid()
{

}

void WINAPI DarkMoonUI::zyLayoutFlexGrid::zyLayoutFlexGrid_Destroy(zyObject* obj)
{
	zyLayout::zyLayout_Destroy(obj);
}
LRESULT WINAPI DarkMoonUI::zyLayoutFlexGrid::zyLayoutFlexGrid_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandled){
	if (uMsg == zyLYM_LAYOUT) {
        zyLayoutFlexGrid* pFlexGrid = (zyLayoutFlexGrid*)obj->getPtrData(L"this");
        pFlexGrid->zyLayoutFlexGrid_Layout(obj);
	}
	else if (uMsg == zyLYM_GETMINSIZE){
        zyLayoutFlexGrid* pFlexGrid = (zyLayoutFlexGrid*)obj->getPtrData(L"this");
		return pFlexGrid->zyLayoutFlexGrid_GetMinSize(obj);
	}
	return zyLayout::zyLayout_WndProc(obj, hWnd, uMsg, wParam, lParam, bHandled);
}
int DarkMoonUI::zyLayoutFlexGrid::zyLayoutFlexGrid_GetMinSize(zyObject* obj) {
    std::vector<int> widths(0);
    std::vector<int> heights(0);
    int minSize = zyLayoutFlexGrid_GetWidthsAndHeights(obj, widths, heights);
    return minSize;
}
void DarkMoonUI::zyLayoutFlexGrid::zyLayoutFlexGrid_Layout(zyObject* obj) {
    // 获取 LayoutItems 并进行类型安全检查
    auto pItems = static_cast<std::vector<zyLayoutItem>*>(obj->getPtrData(L"LayoutItems"));
    if (!pItems || pItems->empty()) return;

    // 获取列数并确保其为正整数
    int ColCount = (int)(LONG_PTR)obj->getPtrData(L"ColCount");
    if (ColCount <= 0) return;

    // 获取矩形区域并进行有效性检查
    RECT* pRect = static_cast<RECT*>(obj->getPtrData(L"pRect"));
    if (!pRect) return;
    RECT rc = *pRect;
    std::vector<int> widths(0);
    std::vector<int> heights(0);
    int minSize = zyLayoutFlexGrid_GetWidthsAndHeights(obj, widths, heights);
    int RowCount = (int)heights.size();
    int posTop = 0;
    for (int i = 0; i < RowCount; i++) {
        int posLeft = 0;
        for (int j = 0; j < ColCount; j++) {
            int index = i * ColCount + j;
            if (index >= pItems->size()) break;

            zyLayoutItem& pItem = (*pItems)[index];
            if (!pItem.pRect || !pItem.pMargin || !pItem.pItemRect) continue;

            RECT rcChild = *pItem.pRect;
            RECT rcMargin = *pItem.pMargin;
            SetRect(pItem.pItemRect, posLeft, posTop, posLeft + widths[j], posTop + heights[i]);
            RECT rcDes = zyGetAlignRectI(*pItem.pItemRect, pItem.align, rcChild.right - rcChild.left, rcChild.bottom - rcChild.top, rcMargin.left, rcMargin.top, rcMargin.right, rcMargin.bottom);
            SetRect(pItem.pRect, rcDes.left, rcDes.top, rcDes.right, rcDes.bottom);

            if (pItem.pObject) {
                try {
                    zyObject* pObject = pItem.pObject;
                    int Type = (int)(LONG_PTR)pObject->getPtrData(L"Type");
                    if (Type == zyLayoutType_Layout) {
                        RtlMoveMemory(pObject->getPtrData(L"pRect"), &rcDes, sizeof(RECT));
                        BOOL bHand = false;
                        pObject->callWndProc(0, zyLYM_LAYOUT, 0, 0, &bHand);
                    } else {
                        HWND hWndItem = reinterpret_cast<HWND>(pObject->getPtrData(L"hWnd"));
                        MoveWindow(hWndItem, rcDes.left, rcDes.top, rcDes.right - rcDes.left, rcDes.bottom - rcDes.top, TRUE);
                    }
                } catch (...) {
                    // 处理异常，确保程序稳定
                    std::cerr << "Error processing layout item at index " << i << std::endl;
                }
            }
            (*pItems)[i * ColCount + j] = pItem;
            posLeft = posLeft + widths[j];
        }
        posTop = posTop + heights[i];
    }
}
int DarkMoonUI::zyLayoutFlexGrid::zyLayoutFlexGrid_GetWidthsAndHeights(zyObject* obj, std::vector<int> &width, std::vector<int> &height) {
    auto pItems = static_cast<std::vector<zyLayoutItem>*>(obj->getPtrData(L"LayoutItems"));
    if (!pItems || pItems->empty()) return 0;
    int minLayoutWidth = 0;
    int minLayoutHeight = 0;
    int ColCount = (int)(LONG_PTR)obj->getPtrData(L"ColCount");
    if (ColCount <= 0) return 0;
    int count = (int)pItems->size();
    int RowCount = count / ColCount + (count % ColCount != 0 ? 1 : 0);
    width.resize(ColCount);
    height.resize(RowCount);
    for (int i = 0; i < RowCount; i++) {
        int minHeight = 0;
        for (int j = 0; j < ColCount; j++) {
            int index = i * ColCount + j;
            if (index >= count) break;

            zyLayoutItem& pItem = (*pItems)[index];
            if (!pItem.pRect || !pItem.pMargin || !pItem.pItemRect) continue;
            if (pItem.pObject) {
                zyObject* pObject = pItem.pObject;
                if ((int)(LONG_PTR)pObject->getPtrData(L"Type") == zyLayoutType_Layout) {
                    BOOL bHand = FALSE;
                    int minSize = (int)(LONG_PTR)pObject->callWndProc(0, zyLYM_LAYOUT, 0, 0, &bHand);
                    pItem.minHeight = HIWORD(minSize);
                    (*pItems)[i * ColCount + j] = pItem;
                }
            }
            RECT rcItem = *pItem.pRect;
            RECT rcMargin = *pItem.pMargin;
            int totalMinWidth = rcItem.bottom - rcItem.top + rcMargin.top + rcMargin.bottom;
            int totalMinHeight = pItem.minHeight + rcMargin.top + rcMargin.bottom;
            if (height[i] < totalMinWidth) {
                height[i] = totalMinWidth;
            }
            if (minHeight < totalMinHeight) {
                minHeight = totalMinHeight;
            }
        }
        minLayoutHeight = minLayoutHeight + minHeight;
    }
    for (int i = 0; i < ColCount; i++) {
        int minWidth = 0;
        for (int j = 0; j < RowCount; j++) {
            int index = j * ColCount + i;
            if (index >= count) break;

            zyLayoutItem& pItem = (*pItems)[index];
            if (!pItem.pRect || !pItem.pMargin || !pItem.pItemRect) continue;
            if (pItem.pObject) {
                zyObject* pObject = pItem.pObject;
                if ((int)(LONG_PTR)pObject->getPtrData(L"Type") == zyLayoutType_Layout) {
                    BOOL bHand = FALSE;
                    int minSize = (int)(LONG_PTR)pObject->callWndProc(0, zyLYM_LAYOUT, 0, 0, &bHand);
                    pItem.minWidth = LOWORD(minSize);
                    (*pItems)[j * ColCount + i] = pItem;
                }
            }
            RECT rcItem = *pItem.pRect;
            RECT rcMargin = *pItem.pMargin;
            int totalMinWidth = rcItem.right - rcItem.left + rcMargin.left + rcMargin.right;
            int totalMinHeight = pItem.minWidth + rcMargin.top + rcMargin.bottom;
            if (width[i] < totalMinWidth) {
                width[i] = totalMinWidth;
            }
            if (minWidth < totalMinHeight) {
                minWidth = totalMinHeight;
            }
        }
        minLayoutWidth = minLayoutHeight + minWidth;
    }
    return MAKEWPARAM(minLayoutWidth, minLayoutHeight);
}
int DarkMoonUI::zyLayoutFlexGrid::列数(int 参数_列数) {
	int ColCount = (int)GetMember(L"ColCount");
	if (参数_列数 > 0) {
		SetMember(L"ColCount", 参数_列数);
	}
	return ColCount;
}
int DarkMoonUI::zyLayoutFlexGrid::取行数() {
	std::vector<zyLayoutItem>* pItems = (std::vector<zyLayoutItem>*)GetMember(L"LayoutItems");
	if (!pItems || pItems->empty()) return 0;
    int count = (int)pItems->size();
	int ColCount = (int)GetMember(L"ColCount");
	if (ColCount <= 0) {
		return 0;
	}
	int RowCount = count / ColCount + (count % ColCount != 0 ? 1 : 0);
	return RowCount;
}